package com.ruoyi.kq.controller;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONWriter;
import com.ruoyi.kq.utils.ImageTextExtractorUtil;
import com.ruoyi.kq.utils.StringParseUtil;
import com.ruoyi.common.core.domain.AjaxResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@RestController
@CrossOrigin
@RequestMapping("/kq/upload")
public class UploadController {

    @Value("${file.upload-dir}")
    private String uploadDir;

    @PostMapping("/photo")
    public AjaxResult uploadPhoto(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            return AjaxResult.error("请选择要上传的文件");
        }

        try {
            // 获取文件大小用于进度计算
            long fileSize = file.getSize();
            long uploadedBytes = 0;

            // 使用缓冲区读取文件
            byte[] buffer = new byte[8192];
            int bytesRead;

            // 创建上传目录
            Path uploadPath = Paths.get(uploadDir);
            if (!Files.exists(uploadPath)) {
                Files.createDirectories(uploadPath);
                log.info("创建文件上传目录：{}", uploadPath.toAbsolutePath());
            } else {
                log.info("文件上传目录已存在：{}", uploadPath.toAbsolutePath());
            }

            // 获取文件后缀
            String originalFilename = file.getOriginalFilename();
            String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
            String newFileName = UUID.randomUUID().toString() + suffix;
            Path filePath = uploadPath.resolve(newFileName);

            log.info("保存文件路径：{}", filePath.toAbsolutePath());

            // 写入文件
            try (InputStream inputStream = file.getInputStream(); 
                 OutputStream outputStream = Files.newOutputStream(filePath)) {

                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                    uploadedBytes += bytesRead;

                    // 计算上传进度
                    int progress = (int) ((uploadedBytes * 100) / fileSize);
                    log.debug("Upload progress: {}%", progress);
                }
            }

            log.info("文件上传成功：{}", filePath);
            
            try {
                // 简单提取整个图像的文字
                String text = ImageTextExtractorUtil.extractText(filePath.toAbsolutePath().toString());
                
                if (StringUtils.isBlank(text)) {
                    log.warn("OCR识别未提取到文字内容");
                    return AjaxResult.error("未能识别图片中的文字，请重新上传清晰的图片");
                }
    
                String s = text.replaceAll("\\s", "");
    
                log.info("OCR源解析清除空白字符数据：{}", s);
    
                if (s.contains("移动打卡")) {
                    s = s.substring(s.indexOf("移动打卡"));
                    log.info("截取'移动打卡'之后的内容：{}", s);
                } else {
                    log.warn("未找到'移动打卡'关键字");
                }
                // 1. 获取有序集合
                Set<String> strings = StringParseUtil.parseInOriginalOrder(s);
                log.info("原解析出的图片信息：\n{}", JSON.toJSONString(strings, JSONWriter.Feature.PrettyFormat));
    
                JSONObject json = new JSONObject();
                // 日期模式
                Pattern datePattern = Pattern.compile("\\d{4}-\\d{2}-\\d{2}");
    
                // 转换为 List（保持插入顺序）
                List<String> list = new ArrayList<>(strings);
    
                int nameIndex = -1;
                mark:
                for (int i = 0; i < list.size(); i++) {
                    String next = list.get(i);
                    Matcher dateMatcher = datePattern.matcher(next);
                    while (dateMatcher.find()) {
                        String date = dateMatcher.group();
                        json.put("today", date);
                        nameIndex = i;
                        break mark;
                    }
                }
    
                if (nameIndex >= 0) {
                    json.put("username", list.get(nameIndex - 1).replace("移动打卡", ""));
                } else {
                    if (StringUtils.isBlank(json.getString("username"))) {
                        try {
                            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
                            String loginName = authentication.getName();
                            json.put("username", loginName);
                            log.info("未找到用户名，使用当前登录用户：{}", loginName);
                        } catch (Exception e) {
                            log.error("获取当前登录用户失败", e);
                            json.put("username", "未知用户");
                        }
                    }
                }
    
                // 分类时间
                String start = StringParseUtil.findEarliestTime(strings);
                String end = StringParseUtil.findNearestAfterTen(strings);
                json.put("firstRecord", start);
                json.put("endRecord", end);
    
                log.info("解析出的图片信息：\n{}", JSON.toJSONString(json, JSONWriter.Feature.PrettyFormat));
    
                return AjaxResult.success(json);
            } catch (Exception e) {
                log.error("OCR图像识别处理失败", e);
                return AjaxResult.error("图像识别处理失败：" + e.getMessage());
            }
        } catch (IOException e) {
            log.error("文件上传失败：", e);
            return AjaxResult.error("文件上传失败：" + e.getMessage());
        }
    }
}